package mvc.core;

import java.io.File;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import mvc.core.annotation.Controller;

public class ConfigParser {

    private static final String PACKAGETOSCAN = "example.action";

    private static Map<String, ActionModel> actionMap = new HashMap<String, ActionModel>();

    public static Map<String, ActionModel> scanPackage() {
        List<String> classes = new ArrayList<String>();
        getClasses(classes, null);
        parseAction(classes);
        return actionMap;
    }

    private static void getClasses(List<String> classes, String packs) {
        String classpath = Thread.currentThread().getContextClassLoader().getResource("").getPath();
        String[] packages = null;
        if (packs != null) {
            packages = packs.split(",");
        } else {
            packages = PACKAGETOSCAN.split(",");
        }
        for (String pack : packages) {
            File file = new File(classpath + pack.replace(".", "/"));
            File[] files = file.listFiles();
            for (File f : files) {
                String fname = f.getName().substring(0, f.getName().lastIndexOf("."));
                if (!f.isDirectory()) {
                    synchronized (classes) {
                        classes.add(pack + "." + fname);
                    }
                } else {
                    getClasses(classes, pack + "." + fname);
                }
            }
        }
    }

    @SuppressWarnings("rawtypes")
    private static void parseAction(List<String> classes) {
        for (String clazzStr : classes) {
            try {
                Class clazz = Class.forName(clazzStr);
                for (Method m : clazz.getMethods()) {
                    Controller c = m.getAnnotation(Controller.class);
                    if (c != null) {
                        ActionModel a = new ActionModel();
                        a.setPath(c.path());
                        a.setMethod(m.getName());
                        a.setActionType(clazzStr);
                        a.setFormType(c.formType());
                        actionMap.put(c.path(), a);
                    }
                }
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}
